---
title: SAIF.Application architecture
summary: Architectural responsibilities, boundaries, and interaction patterns for the base Application-tier abstraction layer of the SAIF BOF stack.
status: draft
owner: SAIF BOF documentation team
last_reviewed: 2026-08-21
library: SAIF.Application
reference_type: embedded
---

# SAIF.Application architecture

SAIF.Application is the base Application-tier abstraction layer of the SAIF BOF stack. It sits between the BOF Framework (`SAIF.BOF.Framework`) and concrete per-domain Application managers (e.g., `SAIF.Application.Claim`, `SAIF.Application.Claim.Legal`), defining the shared contract and plumbing — security-role state, context-set tracking, message accumulation, and a data-portal bootstrap wrapper — that every concrete "AppManager" class in the solution must implement.*

## Responsibilities
- Define the abstract application-manager lifecycle contract (`Initialize` → `OnInitialize` → `OnCreateDataLayer`; `OnCheckSecurity`; `OnTransactionStart`/`OnWrite`/`OnTransactionStop`; `OnRetrieve`) that every concrete `AppManagerBase` subclass must implement.
- Bootstrap and register named data-access portals (SQL Server and/or Oracle) via `ApplicationDataAccess`, for use by concrete business/application objects.
- Provide an authorization-caching contract (`UserAccess`) over caller-supplied AD resource names, backed by `clsSecurityPrincipal.IsAuthorized`.
- Provide a lighter-weight, non-`clsBusinessBase` service-manager base (`clsServiceAppManagerBase`) plus a service-oriented result contract (`ServiceResponse`/`ServiceMessage`) for WCF/service-style application managers.
- Provide cross-cutting message-formatting utilities (`MessageFormatting`) for Windows- and Web-style display of accumulated message lists.

## Component boundaries
- **`AppManagerBase`**: orchestration contract — abstract lifecycle, security-role state (`AppSecurityRole`), context-set tracking, and message accumulation. Inherits `clsBusinessBase`†, making every concrete AppManager simultaneously a BOF business object and an application-process controller with its own parallel lifecycle.
- **`ApplicationDataAccess`**: data-access-layer bootstrap — wraps `clsDataAccess` and holds a named collection of `IDataPortalInfo` instances, exposing `CreateSQLServerPortal`/`CreateOraclePortal` and a `DPI(key)` accessor.
- **`UserAccess`**: authorization-caching contract — abstract base providing `HasAccess`/`CheckAccess` over AD resource names, with per-instance result caching.
- **`clsServiceAppManagerBase`**: lightweight service-style application-manager base (holds only an `IDataPortalInfo` reference), used with `ServiceMessage`/`ServiceResponse`/`ServiceMessageType` to build a service-oriented result contract distinct from `AppManagerBase`'s UI-message-string approach.
- **`MessageFormatting`**: standalone, static utility for concatenating message lists into display strings (CRLF, `<BR>`, or caller-supplied separator); independent of any other class in the library.
- **`AppConstants`**: minimal shared-constants holder (`SAIFVALUE = "SAIF"`).

## Interaction model
- Concrete Application-tier managers (out of scope of this library) subclass `AppManagerBase`, supplying the abstract `On*` hooks; `AppManagerBase` itself contains no concrete business or retrieval logic.
- `AppManagerBase.OnCreateDataLayer()` (subclass-implemented) is expected to populate the lazily-created `DataLayer` (`ApplicationDataAccess`) with one or more named data portals, or to inject a pre-built portal via `AppManagerBase.InjectDPI`.
- `ApplicationDataAccess.CreateSQLServerPortal`/`CreateOraclePortal` delegate to `SAIF.BOF.Framework` to construct `clsSQLDataPortal`/`clsMSOracleDataPortal` instances and register them with the framework's `clsDataAccess`/`IDataAccess`.
- `UserAccess`-derived types delegate authorization decisions to `clsSecurityPrincipal.IsAuthorized(resourceName)` (from `SAIF.BOF.Framework.Security`), caching each result for the life of the instance.
- No calls to the inherited `clsBusinessBase` rule/edit/save machinery (`Rules`, `BeginEdit`, the inherited save path) are made anywhere in this library's own code* — the framework business-object lifecycle inherited via `clsBusinessBase`† and `AppManagerBase`'s own `OnInitialize`/`OnRetrieve`/`OnWrite` lifecycle coexist but are used independently here.
- `clsServiceAppManagerBase`/`ServiceResponse` follow an independent interaction path: a service-style manager constructs a `ServiceResponse`, appends `ServiceMessage` entries via `AddErrorMessage`/`AddWarningMessage`/`AddInformationMessage`/`AddEnvironmentMessage`, and callers read the aggregated, type-filtered message collections.

## Design constraints
- Every concrete `AppManagerBase` subclass must implement all `MustOverride` members (`OnInitialize`, `OnCreateDataLayer`, `OnContextChanged`, `OnCheckSecurity`, `OnTransactionStart`, `OnTransactionStop`, `OnRetrieve`, `OnWrite`, `OnValidContext`, `Retrieve`, `Write`); the VB.NET compiler prevents instantiation otherwise.
- `AppManagerBase` inherits `clsBusinessBase`†, which owns a `clsRulesManager` instance and is tied to the framework's V1 rules engine†, but no evidence in this library shows those inherited rule/edit/save members being invoked — the design constraint is that the base class's dual lifecycles are independent, not integrated, in this library's own code.*
- Two distinct, identically-named `AppSecurityRole` enum declarations exist (nested in `AppManagerBase` vs. top-level in `Enums.vb`); which one downstream consumers reference could not be determined from this library alone.**
- No AD resource-name literals are declared in this library — `UserAccess` is a generic mechanism whose concrete resource names must be supplied entirely by callers/subclasses.
- This library authors and executes no SQL; it is strictly a connection/data-portal bootstrap layer for `SAIF.BOF.Framework`'s SQL Server and Oracle (ODP.NET) data portals.
- `AppViewPageBase.aspx` declares `Inherits="AppMVCBase.AppViewPageBase"`, a type not defined anywhere in this library and not referenced by the `.vbproj`; it appears to be an orphaned/legacy artifact whose real runtime owner could not be determined from this library's scope.**

## Architecture diagram
The following diagram shows the responsibility layers within SAIF.Application and its direct external dependencies.

```mermaid
flowchart TD
    subgraph SAIFApplication["SAIF.Application (this library)"]
        AMB["AppManagerBase<br>(abstract lifecycle + security role)"]
        ADA["ApplicationDataAccess<br>(DPI/portal registry)"]
        UA["UserAccess<br>(AD resource cache)"]
        CSAB["clsServiceAppManagerBase<br>(service-style base)"]
        MF["MessageFormatting<br>(message concatenation)"]
        SR["ServiceResponse / ServiceMessage<br>(Service Based)"]
    end
    FW["SAIF.BOF.Framework<br>clsBusinessBase, clsSecurityPrincipal,<br>clsDataAccess, IDataPortalInfo"]
    ORA["Oracle.ManagedDataAccess<br>(ODP.NET)"]

    AMB -->|Inherits| FW
    AMB -->|owns| ADA
    AMB -->|reads| UAtxt["clsSecurityPrincipal (via SecurityPrincipal)"]
    UA -->|calls IsAuthorized| FW
    ADA -->|creates portals via| FW
    ADA -->|Oracle portal| ORA
    CSAB -->|holds| FW
```

## Sequence diagram
The following diagram shows the primary application-manager initialization and data-portal registration sequence.

```mermaid
sequenceDiagram
	participant Caller as Concrete AppManager subclass
	participant AMB as AppManagerBase
	participant ADA as ApplicationDataAccess
	participant FW as SAIF.BOF.Framework

	Caller->>AMB: New(inSecurityPrincipal)
	Caller->>AMB: Initialize()
	AMB->>Caller: OnInitialize() (abstract hook)
	AMB->>Caller: OnCreateDataLayer() (abstract hook)
	Caller->>ADA: CreateSQLServerPortal(key) / CreateOraclePortal(key)
	ADA->>FW: New clsSQLDataPortal / New clsMSOracleDataPortal
	ADA->>FW: DAL.AddDataPortal(portal, portalID & key)
	FW-->>ADA: IDataPortalInfo
	ADA-->>Caller: DPI(key) available
```

## Inherited framework context (`clsBusinessBase`)
`AppManagerBase` inherits `clsBusinessBase` from `SAIF.Framework.Core` (1 occurrence in this library, per the framework-density scan). Per cached Legends CLI RAG findings retrieved for `clsBusinessBase`:
- Public members include `Rules` (`clsRulesManager`), `BeginEdit`/`CancelEdit`/`ApplyEdit`, link-management methods (`SetPreviousLink`, `SetNextLink`, `InsertLinkAfter`, `InsertLinkBefore`, `RemoveLinks`), and `IDataErrorInfo` support (`Error`, `Item(columnName)`); inherited members further up the chain include `DumpState()` and `AllowCache`.†
- `clsBusinessBase` owns a `clsRulesManager` instance and is tied to the framework's V1 rules engine — no code in `SAIF.Framework.Core` was observed wiring V2 rule types into the base classes.†
- Available lifecycle operations inherited from `clsBusinessBase` include edit-session management (open/commit/roll back), rule evaluation in severity order, save (validate + dispatch insert/update/delete), create/retrieve via the data-portal dispatch path, and (for API-backed criteria) API client/route resolution.†
- `Save()`/`SaveChild()` throw `ApplicationException` if the target is read-only, in the wrong root/child role, still inside an edit level, or invalid after rule evaluation; `CreateObject`/`RetrieveObject` wrap lower-level failures in `ApplicationException` and disconnect the portal in a `Finally` block.†
- No direct evidence in `AppManagerBase.vb` shows these inherited members being overridden or called; `AppManagerBase` instead layers its own parallel `MustOverride` lifecycle contract on top of the inherited `clsBusinessBase` surface.*

## Security architecture summary
- Authorization is centralized and AD-resource-name-based, delegated to the framework: `UserAccess` consumes `clsSecurityPrincipal.IsAuthorized(resourceName)` from `SAIF.BOF.Framework.Security` as the single point of truth for AD-resource authorization, with no AD lookup implemented directly in this library.
- `AppManagerBase` layers a separate, whole-object role-gating mechanism (`AppSecurityRole` + `Mark*`/`Is*` members) on top of `UserAccess`'s per-resource checks; no wiring between the two mechanisms is visible in this library.*
- Until a concrete subclass's `OnCheckSecurity()` implementation explicitly marks the security role, `AppManagerBase` defaults to `NoAccess` (fail-closed).*

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `*` were inferred
> from code structure or contextual evidence. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [API reference](api/index.md)

## Sources
- `SAIF.Application\AppManagerBase.vb`
- `SAIF.Application\ApplicationDataAccess.vb`
- `SAIF.Application\UserAccess.vb`
- `SAIF.Application\clsServiceAppManagerBase.vb`
- `SAIF.Application\MessageFormatting.vb`
- `SAIF.Application\AppConstants.vb`
- `SAIF.Application\Enums.vb`
- `SAIF.Application\AppViewPageBase.aspx`
- `SAIF.Application\Service Based\ServiceEnums.vb`
- `SAIF.Application\Service Based\ServiceMessage.vb`
- `SAIF.Application\Service Based\ServiceResponse.vb`
- `SAIF.Application\SAIF.Application.vbproj`
- `SAIF.Application\packages.config`
- Legends CLI RAG service (indexed documentation for `clsBusinessBase`, source library `SAIF.Framework.Core`)
